import { $TSContext } from '@aws-amplify/amplify-cli-core';
import { printer } from '@aws-amplify/amplify-prompts';
import type { Form } from '@aws-sdk/client-amplifyuibuilder';
import { AmplifyStudioClient } from '../clients';
import { isFormDetachedFromModel, isFormSchemaCustomized, shouldRenderComponents } from '../commands/utils';
import { ModelIntrospectionSchema } from '@aws-amplify/appsync-modelgen-plugin';

/**
 * Handles showing a warning for detached forms pre-push.
 */
export const prePushHandler = async (context: $TSContext): Promise<void> => {
  if (!(await shouldRenderComponents(context))) {
    return;
  }
  const studioClient = await AmplifyStudioClient.setClientInfo(context);
  const [formSchemas, localSchema] = await Promise.all<
    [
      Promise<{
        entities: Form[];
      }>,
      Promise<ModelIntrospectionSchema>,
    ]
  >([studioClient.listForms(), context.amplify.invokePluginMethod(context, 'codegen', undefined, 'getModelIntrospection', [context])]);

  if (!localSchema) {
    printer.debug('Local schema not found');
    return;
  }
  printDetachedFormsWarning(formSchemas, localSchema);
};

const printDetachedFormsWarning = (formSchemas: { entities: Form[] }, localSchema: ModelIntrospectionSchema): void => {
  const modelNames = new Set(Object.keys(localSchema.models));
  const detachedCustomForms: string[] = [];

  formSchemas.entities.forEach((form) => {
    // Only show warnings for schema's that have customization, otherwise it's the same as
    // an autogenerated form.
    if (isFormDetachedFromModel(form, modelNames) && isFormSchemaCustomized(form) && form.name) {
      detachedCustomForms.push(form.name);
    }
  });

  if (detachedCustomForms.length > 0) {
    printer.warn(
      `The following form${
        detachedCustomForms.length === 1 ? '' : 's'
      } will no longer be available because the connected data model no longer exists: ${detachedCustomForms.join(', ')}`,
    );
  }
};
